// import OSS from 'ali-oss';
import { Message } from '@arco-design/web-react';
import axios, { AxiosInstance, AxiosProgressEvent, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { logoutRequest } from './redux/logoutReducer';
import store from './redux/store';
import { LoginUser } from './types';
import { HttpStatus } from './utils/RespEnum';
import cache from './utils/cache';
import {
  decryptBase64,
  decryptWithAes,
  encryptBase64,
  encryptWithAes,
  generateAesKey,
  tansParams,
} from './utils/crypto';
import { decrypt, encrypt } from './utils/jsencrypt';

/**
 * 界面样式
 * @layout1 海量样式
 * @layout2 顶部是头，中左侧是可展开菜单
 */
type LayoutType = 'layout1' | 'layout2';
// 页面添加水印
function handleWatermark(show: boolean) {
  let old = document.getElementById('watermark') as unknown as HTMLElement;
  if (old) {
    document.body.removeChild(old);
  }
  if (show) {
    let div = document.createElement('div');
    div.setAttribute('class', 'd-flex-r flex-wrap');
    div.setAttribute('id', 'watermark');
    div.setAttribute(
      'style',
      'pointer-events:none;position: fixed; z-index: 99999999; width: 100%; height: 100%; overflow: hidden;left:0;top:0;'
    );
    for (let i = 0; i < 50; i++) {
      let sub = document.createElement('div');
      sub.setAttribute('class', 'font-18');
      sub.setAttribute('style', `color:#d5d5d5;opacity: 0.3; transform:rotate(-30deg);padding:80px;`);
      sub.appendChild(document.createTextNode(main.user?.nickName || main.projectName));
      div.appendChild(sub);
    }
    document.body.appendChild(div as unknown as HTMLElement);
  }
}

export class AppLocalKey {
  // 登录token
  static loginToken = 'loginToken';
  /// 记住登录账号
  static loginUsername = 'loginUsername';
  /// 记住登录密码
  static loginPassword = 'loginPassword';
  /// 是否记住登录密码 'true' / 'false' 字符串类型
  static loginIsRember = 'loginIsRember';
  /// 皮肤设置
  static theme = 'theme';
}

class Theme {
  default = 'default';

  themes = {
    [this.default]: `
      @--bg-primary:40, 52, 102;
      @--primary-6:71, 107, 245;
      @--primary-5:98, 128, 250;
      @--text-default-color:50, 65, 87;
      @--text-second-color:136, 146, 181;
      @--page-bg-color:242, 244, 247;
      @--border-color:235, 237, 242;
    `,
  };
  init() {
    let theme = localStorage.getItem(AppLocalKey.theme) ?? this.default;
    if (theme && this.themes[theme]) {
      document.body.setAttribute('style', this.themes[theme]);
    }
  }
  setTheme(theme: string) {
    if (theme && this.themes[theme]) {
      document.body.setAttribute('style', this.themes[theme]);
      localStorage.setItem(AppLocalKey.theme, theme);
    }
  }
}

const encryptHeader = 'encrypt-key';

class Main {
  // 项目名称
  projectName: string = '卡管家';
  // 是否开启水印
  watermark: boolean = false;
  // 添加水印的方法
  createWatermark = handleWatermark;
  //  布局类型
  layout: LayoutType = 'layout1';

  theme: Theme = new Theme();

  /** 客户端ID */
  clientId: string = 'e5cd7e4891bf95d1d19206ce24a7b32e';
  // 接口加密功能开关(如需关闭 后端也必须对应关闭)
  VITE_APP_ENCRYPT = 'true';

  api: AxiosInstance = axios.create({
    baseURL: '/api',
    timeout: 120000,
    headers: {
      clientId: this.clientId,
      'Content-Type': 'application/json;charset=utf-8',
    },
    onUploadProgress(progressEvent: AxiosProgressEvent) {
      if (main.uploadProgress) {
        main.uploadProgress(progressEvent.loaded, progressEvent.total ?? 0);
      }
    },
  });
  uploadProgress?: (loaded: number, total: number) => void;
  /** 各页面当前页码 按页面标签区分 */
  currPageNum: { [x: string]: number } = {};
  /** 各页面当前记录数量 按页面标签区分 */
  currPageSize: { [x: string]: number } = {};
  /** 各页面当前搜索状态 按页面标签区分 */
  currPageState: { [x: string]: { [x: string]: any } } = {};
  defaultPageSize: number = 12;
  defaultPageSizeOptions: number[] = [10, 12, 20, 30, 50, 100];
  user?: LoginUser;
  permissions?: string[];
  roles?: string[];
  loginKey?: string | null;
  ossBasePath = 'importExcel/';
  // aliOssClient = new OSS({
  //   region: 'oss-cn-shanghai',
  //   accessKeyId: 'LTAI5t9Xvri1oydhe4wXfFto',
  //   accessKeySecret: 'SAiYTIOupm3Uh9edmeSPTVWLmx25rv',
  //   bucket: 'jk-card',
  //   endpoint: 'oss-cn-shanghai.aliyuncs.com',
  // });

  init() {
    document.title = this.projectName;
    // 皮肤初始化
    this.theme.init();
    // 水印初始化
    if (this.watermark) {
      handleWatermark(true);
    }
    // 请求拦截器
    this.api.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        const isToken = config.headers?.isToken === false;
        // 是否需要防止数据重复提交
        const isRepeatSubmit = config.headers?.repeatSubmit === false;
        // 是否需要加密
        const isEncrypt = config.headers?.isEncrypt === 'true';

        if (this.loginKey && !isToken) {
          config.headers['Authorization'] = 'Bearer ' + this.loginKey; // 让每个请求携带自定义token 请根据实际情况自行修改
        }
        if (config.url?.includes('/gen')) {
          config.headers['datasource'] = 'master';
        }
        // get请求映射params参数
        if (config.method === 'get' && config.params) {
          let url = config.url + '?' + tansParams(config.params);
          url = url.slice(0, -1);
          config.params = {};
          config.url = url;
        }

        if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
          const requestObj = {
            url: config.url,
            data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
            time: new Date().getTime(),
          };
          const sessionObj = cache.session.getJSON('sessionObj');
          if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
            cache.session.setJSON('sessionObj', requestObj);
          } else {
            const s_url = sessionObj.url; // 请求地址
            const s_data = sessionObj.data; // 请求数据
            const s_time = sessionObj.time; // 请求时间
            const interval = 500; // 间隔时间(ms)，小于此时间视为重复提交
            if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
              const message = '数据正在处理，请勿重复提交';
              return Promise.reject(new Error(message));
            } else {
              cache.session.setJSON('sessionObj', requestObj);
            }
          }
        }
        if (this.VITE_APP_ENCRYPT === 'true') {
          // 当开启参数加密
          if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
            // 生成一个 AES 密钥
            const aesKey = generateAesKey();
            config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
            config.data =
              typeof config.data === 'object'
                ? encryptWithAes(JSON.stringify(config.data), aesKey)
                : encryptWithAes(config.data, aesKey);
          }
        }
        // FormData数据去请求头Content-Type
        if (config.data instanceof FormData) {
          delete config.headers['Content-Type'];
        }
        return config;
      },
      (error: any) => {
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.api.interceptors.response.use(
      (res: AxiosResponse) => {
        if (this.VITE_APP_ENCRYPT === 'true') {
          // 加密后的 AES 秘钥
          const keyStr = res.headers[encryptHeader];
          // 加密
          if (!!keyStr) {
            const data = res.data;
            // 请求体 AES 解密
            const base64Str = decrypt(keyStr);
            // base64 解码 得到请求头的 AES 秘钥
            const aesKey = decryptBase64(base64Str.toString());
            // aesKey 解码 data
            const decryptData = decryptWithAes(data, aesKey);
            // 将结果 (得到的是 JSON 字符串) 转为 JSON
            res.data = JSON.parse(decryptData);
          }
        }
        // 未设置状态码则默认成功状态
        const code = res.data.code || HttpStatus.SUCCESS;
        // 二进制数据则直接返回
        if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
          return res;
        }
        if (code === 401) {
          store.dispatch(logoutRequest());

          if (!window.location.href.includes('/login')) {
            window.location.href = '/login';
          }
          return Promise.reject('无效的会话，或者会话已过期，请重新登录。');
        } else {
          return Promise.resolve(res);
        }
      },
      (error: any) => {
        let { message } = error;
        if (message === 'Network Error') {
          message = '后端接口连接异常';
        } else if (message.includes('timeout')) {
          message = '系统接口请求超时';
        } else if (message.includes('Request failed with status code')) {
          message = '系统接口' + message.substr(message.length - 3) + '异常';
        }
        Message.error({ content: message, duration: 5 * 1000 });
        return Promise.reject(error);
      }
    );
  }

  /** 设置当前页码 同时清除别的页面页码 再进别的页面就是第1页 但检索条件不变  */
  setPageNum(tag: string, num: number) {
    this.currPageNum = { [tag]: num };
  }
}

let main: Main = new Main();
export default main;
